//my buffer package
package medusa

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
)

/*
type ByteBuffer2 bytes.Buffer;

func BindBuffer(databuf []byte)*ByteBuffer2{

	return (*ByteBuffer2)(bytes.NewBuffer(databuf))
}

*/

//type ByteBuffer bytes.Buffer

type ByteBuffer struct {
	bytes.Buffer
	//data_buffer *bytes.Buffer
}

func NewByteBuffer() *ByteBuffer {

	buf := new(ByteBuffer)

	//buf.data_buffer = new(bytes.Buffer)//make([]byte, size)
	//buf := new(ByteBuffer)

	return buf
}

func BindByteBuffer(databuf []byte) *ByteBuffer {
	return &ByteBuffer{*bytes.NewBuffer(databuf)}
}

/*
func (self *ByteBuffer) ReadDataFromIO(fd io.Reader) (written int64, err error) {
	written, err = io.ReadFull(self, fd)
	//fmt.Println ("error:",  err, "self-len", self.Len ())
	return written, err
}*/

//func (self *ByteBuffer)Len() int{
//	return self.Len()
//}

func (self *ByteBuffer) Clear() {
	self.Reset()
}

//Boolean
func (self *ByteBuffer) ReadBoolean() bool {
	var value byte
	binary.Read(self, binary.LittleEndian, &value)
	return value != 0
}
func (self *ByteBuffer) WriteBoolean(value bool) {
	/*
		err := binary.Write(self, binary.LittleEndian, value)
		if err != nil {
			fmt.Println("binary.Write failed:", err)
		}*/
	if value {
		self.WriteByte(1)
	} else {
		self.WriteByte(0)
	}
}

//Byte
func (self *ByteBuffer) ReadByte() byte {
	var value byte
	//buf :=self.Bytes()
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteByte(value byte) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Int8
func (self *ByteBuffer) ReadInt8() int8 {
	var value int8
	//buf :=self.Bytes()
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteInt8(value int8) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Uint8
func (self *ByteBuffer) ReadUint8() uint8 {
	var value uint8
	//buf :=self.Bytes()
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteUint8(value uint8) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Int16
func (self *ByteBuffer) ReadInt16LE() int16 {
	var value int16
	binary.Read(self, binary.LittleEndian, &value)
	return value
}

func (self *ByteBuffer) WriteInt16LE(value int16) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadInt16BE() int16 {
	var value int16
	binary.Read(self, binary.BigEndian, &value)
	return value
}
func (self *ByteBuffer) WriteInt16BE(value int16) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Uint16
func (self *ByteBuffer) ReadUint16LE() uint16 {
	var value uint16
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteUint16LE(value uint16) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadUint16BE() uint16 {
	var value uint16
	binary.Read(self, binary.BigEndian, &value)
	return value
}
func (self *ByteBuffer) WriteUint16BE(value uint16) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Int32
func (self *ByteBuffer) ReadInt32LE() int32 {
	var value int32
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteInt32LE(value int32) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadInt32BE() int32 {
	var value int32
	binary.Read(self, binary.BigEndian, &value)
	return value
}
func (self *ByteBuffer) WriteInt32BE(value int32) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Uint32
func (self *ByteBuffer) ReadUint32LE() uint32 {
	var value uint32
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteUint32LE(value uint32) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadUint32BE() uint32 {
	var value uint32
	binary.Read(self, binary.BigEndian, &value)
	return value
}
func (self *ByteBuffer) WriteUint32BE(value uint32) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Int64
func (self *ByteBuffer) ReadInt64LE() int64 {
	var value int64
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteInt64LE(value int64) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadInt64BE() int64 {
	var value int64
	binary.Read(self, binary.BigEndian, &value)
	return value
}
func (self *ByteBuffer) WriteInt64BE(value int64) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Uint64
func (self *ByteBuffer) ReadUint64LE() uint64 {
	var value uint64
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteUint64LE(value uint64) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadUint64BE() uint64 {
	var value uint64
	binary.Read(self, binary.BigEndian, &value)
	return value
}
func (self *ByteBuffer) WriteUint64BE(value uint64) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Float32
func (self *ByteBuffer) ReadFloat32LE() float32 {
	var value float32
	binary.Read(self, binary.LittleEndian, &value)
	return value
}
func (self *ByteBuffer) WriteFloat32LE(value float32) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadFloat32BE() float32 {
	var value float32
	binary.Read(self, binary.BigEndian, &value)
	return value
}
func (self *ByteBuffer) WriteFloat32BE(value float32) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Float64
func (self *ByteBuffer) ReadFloat64LE() float64 {
	var value float64
	binary.Read(self, binary.LittleEndian, &value)
	return value
}

func (self *ByteBuffer) WriteFloat64LE(value float64) {

	err := binary.Write(self, binary.LittleEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadFloat64BE() float64 {
	var value float64
	binary.Read(self, binary.BigEndian, &value)
	return value
}

func (self *ByteBuffer) WriteFloat64BE(value float64) {

	err := binary.Write(self, binary.BigEndian, value)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//String
/*
func (self *ByteBuffer) ReadString(size int) string {
	var value []byte = make([]byte, size)
	binary.Read(self, binary.LittleEndian, value)
	return string(value)
}*/

func (self *ByteBuffer) ReadStringBySep(sep byte) string {
	var value []byte = make([]byte, 1024)
	i := 0
	for {
		b := self.ReadByte()
		if b == sep {
			break
		}
		value[i] = b
		i = i + 1
	}
	return string(value[0:i])
}

func (self *ByteBuffer) ReadLine() string {
	return self.ReadStringBySep('\n')
}

func (self *ByteBuffer) WriteLine(value string) {
	str := []byte(value)
	err := binary.Write(self, binary.LittleEndian, str[:])
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
	//var b byte = '\n'
	err = binary.Write(self, binary.LittleEndian, '\n')
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

func (self *ByteBuffer) ReadString() string {

	size := self.ReadInt16BE()
	value := make([]byte, size)
	binary.Read(self, binary.BigEndian, value)
	return string(value[0:size])
}

func (self *ByteBuffer) WriteString(value string) {
	str := []byte(value)
	self.WriteInt16BE((int16)(len(value)))
	err := binary.Write(self, binary.LittleEndian, str[:])
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}
}

//Buffer
//func io.CopyN(dst Writer, src Reader, n int64) (written int64, err error)
func (self *ByteBuffer) WriteBufferToWriter(dst io.Writer, n int) (int, error) {
	readed, err := io.CopyN(dst, self, (int64)(n))
	return (int)(readed), err
}

func (self *ByteBuffer) ReadBufferFromReader(src io.Reader, n int) (int, error) {
	written, err := io.CopyN(self, src, (int64)(n))
	return (int)(written), err
}

//Buffer32
func (self *ByteBuffer) WriteBufferToWriter32(dst io.Writer, n int32) (int32, error) {
	readed, err := io.CopyN(dst, self, (int64)(n))
	return (int32)(readed), err
}

func (self *ByteBuffer) ReadBufferFromReader32(src io.Reader, n int32) (int32, error) {
	written, err := io.CopyN(self, src, (int64)(n))
	return (int32)(written), err
}

//Buffer64
func (self *ByteBuffer) WriteBufferToWriter64(dst io.Writer, n int64) (written int64, err error) {
	written, err = io.CopyN(dst, self, n)
	return
}

func (self *ByteBuffer) ReadBufferFromReader64(src io.Reader, n int64) (written int64, err error) {
	written, err = io.CopyN(self, src, n)
	return
}
